package com.tom.sen.base;

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.BeanProperty;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.ser.ContextualSerializer;
import com.tom.sen.annotation.SensitiveInfo;
import com.tom.sen.util.AuthUtil;
import com.tom.sen.util.SensitiveInfoUtils;

import java.io.IOException;
import java.util.Objects;

public class SensitiveInfoSerialize  extends JsonSerializer<String> implements ContextualSerializer {
    /**接收注解脱敏类型*/
    private SensitiveType type;
    /**接收可查看的权限*/
    private SensitiveRole role;
    public SensitiveInfoSerialize() {
    }
    public SensitiveInfoSerialize(final SensitiveType type ,final SensitiveRole role ) {
        this.type = type;
        this.role = role;
    }
    /**序列化的逻辑处理
     */
    @Override
    public void serialize(final String s, final JsonGenerator jsonGenerator,
                          final SerializerProvider serializerProvider)
            throws IOException, JsonProcessingException {
        if (hasRole(SensitiveRole.seer.name())){
            //有权限,显示原文
            jsonGenerator.writeString(s);
            return;
        }
        if (hasRole(SensitiveRole.no_seer.name())){
            //有权限,显示原文
            jsonGenerator.writeString(SensitiveInfoUtils.password(s));
            return;
        }
        if (hasRole(role.name())){
            //有权限,显示原文
            jsonGenerator.writeString(s);
            return;
        }
        switch (this.type) {
            case CHINESE_NAME: {
                if (hasRole(SensitiveRole.name_seer.name())){
                    //有权限,显示原文
                    jsonGenerator.writeString(s);
                }else{
                    jsonGenerator.writeString(SensitiveInfoUtils.chineseName(s));
                }
                break;
            }
            case ID_CARD: {
                if (hasRole(SensitiveRole.id_card_seer.name())){
                    //有权限,显示原文
                    jsonGenerator.writeString(s);
                }else{
                    jsonGenerator.writeString(SensitiveInfoUtils.idCardNum(s));
                }
                break;
            }
            case FIXED_PHONE: {
                if (hasRole(SensitiveRole.fixed_phone_seer.name())){
                    //有权限,显示原文
                    jsonGenerator.writeString(s);
                }else{
                    jsonGenerator.writeString(SensitiveInfoUtils.fixedPhone(s));
                }
                break;
            }
            case MOBILE_PHONE: {
                if (hasRole(SensitiveRole.mobile_phone_seer.name())){
                    //有权限,显示原文
                    jsonGenerator.writeString(s);
                }else{
                    jsonGenerator.writeString(SensitiveInfoUtils.mobilePhone(s));
                }
                break;
            }
            case ADDRESS: {
                if (hasRole(SensitiveRole.address_seer.name())){
                    //有权限,显示原文
                    jsonGenerator.writeString(s);
                }else{
                    jsonGenerator.writeString(SensitiveInfoUtils.address(s, 8));
                }
                break;
            }
            case EMAIL: {
                if (hasRole(SensitiveRole.email_seer.name())){
                    //有权限,显示原文
                    jsonGenerator.writeString(s);
                }else{
                    jsonGenerator.writeString(SensitiveInfoUtils.email(s));
                }
                break;
            }
            case BANK_CARD: {
                if (hasRole(SensitiveRole.bank_card_seer.name())){
                    //有权限,显示原文
                    jsonGenerator.writeString(s);
                }else{
                    jsonGenerator.writeString(SensitiveInfoUtils.bankCard(s));
                }
                break;
            }
            case CNAPS_CODE: {
                if (hasRole(SensitiveRole.cnaps_code_seer.name())){
                    //有权限,显示原文
                    jsonGenerator.writeString(s);
                }else{
                    jsonGenerator.writeString(SensitiveInfoUtils.cnapsCode(s));
                }
                break;
            }
            case PASSWORD: {
                if (hasRole(SensitiveRole.seer.name())){
                    //有权限,显示原文
                    jsonGenerator.writeString(s);
                }else{
                    jsonGenerator.writeString(SensitiveInfoUtils.password(s));
                }
                break;
            }
            case ACCOUNT_NO: {
                if (hasRole(SensitiveRole.account_no_seer.name())){
                    //有权限,显示原文
                    jsonGenerator.writeString(s);
                }else{
                    jsonGenerator.writeString(SensitiveInfoUtils.account(s));
                }
                break;
            }
        }
    }
    /**自定义注解被拦截后的回调函数*/
    @Override
    public JsonSerializer<?> createContextual(final SerializerProvider
                                                      serializerProvider,final BeanProperty beanProperty) throws JsonMappingException {
        if (beanProperty != null) { // 为空直接跳过
            if (Objects.equals(beanProperty.getType().getRawClass(), String.class)) {
                // 非 String 类直接跳过
                SensitiveInfo sensitiveInfo =
                        beanProperty.getAnnotation(SensitiveInfo.class);
                if (sensitiveInfo == null) {
                    sensitiveInfo =
                            beanProperty.getContextAnnotation(SensitiveInfo.class);
                }
                if (sensitiveInfo != null) {
                    // 如果能得到注解，就将注解的 value 传入 SensitiveInfoSerialize
                    return new SensitiveInfoSerialize(sensitiveInfo.type(),sensitiveInfo.role());
                }
            }
            return serializerProvider.findValueSerializer(beanProperty.getType(), beanProperty);
        }
        return serializerProvider.findNullValueSerializer(beanProperty);
    }
    /**
     * 判断接口是否有任意xxx，xxx权限
     * 这里写的是Spring Security的判断方式，如果使用的是shiro可以参考注掉的那两行代码，如果使用的其他的认证框架，自行参考实现逻辑
     * @param role 角色符
     * @return {boolean}
     */
    public boolean hasRole(String role) {

        return AuthUtil.checkRole(role);

    }
}

